import { app } from "../../base/typings/global";

/**
 * ABTesting的比例枚举
 */
export enum ABTestingProportion {
    /**
     * 关闭
     */
    Zero = 0,
    One,
    Two,
    Three,
    /**
     * 半量
     */
    Half,
    Five,
    Six,
    Seven,
    Eight,
    Nine,
    /**
     * 全量
     */
    Full
}

enum ABTestingFlag {
    Invalid,
    Valid
};

type Flags = { [key: string]: ABTestingFlag };

/**
 * ABTesting配置
 */
export type ABTestingConfig = {
    [key: string]: ABTestingProportion
}

class ABTesting {
    private _config: ABTestingConfig = {};
    private _flags: Flags = {};

    constructor() {

    }

    /**
     * 设置ABTesting的flag配置，config格式为```{[key:string]:ABTestingProportion}```
     * @param config 一个config
     * @param args 更多的config
     */
    public setFlagConfigs(config: ABTestingConfig, ...args: ABTestingConfig[]): void {
        args.unshift(config);
        for (let i = 0; i < args.length; i++) {
            const configItem = args[i];
            for (const key in configItem) {
                if (Object.prototype.hasOwnProperty.call(configItem, key)) {
                    const proportion = configItem[key];
                    if (Object.prototype.hasOwnProperty.call(this._config, key)) {
                        console.warn(`[ABTesting]重新设置${key}的占比，之前的取值不会生效。`);
                    }
                    this._config[key] = proportion;
                }
            }
        }
    }

    /**
     * 获取当前启动粒度的flag
     * @param key flag的key，需要先调用setFlagConfigs进行配置，否则固定返回Invalid
     * @returns 
     */
    public getLaunchFlag(key: string): ABTestingFlag {
        if (!Object.prototype.hasOwnProperty.call(this._config, key)) {
            console.warn(`[ABTesting]未设置${key}的占比设置, 默认返回Invalid.`);
            return ABTestingFlag.Invalid;
        }
        if (this._flags['l' + key] != null) {
            return this._flags[key];
        }
        let flag: ABTestingFlag = app.App.launchTime % 10 <= this._config[key] ? ABTestingFlag.Valid : ABTestingFlag.Invalid;
        this._flags['l' + key] = flag;
        app.publisher.analytics.setProperty('l' + key, flag);
        return flag;
    }

    /**
     * 获取客户端安装粒度的flag
     * @param key flag的key，需要先调用setFlagConfigs进行配置，否则固定返回Invalid
     * @returns 
     */
    public getInstallFlag(key: string): ABTestingFlag {
        if (!Object.prototype.hasOwnProperty.call(this._config, key)) {
            console.warn(`[ABTesting]未设置${key}的占比设置, 默认返回Invalid.`);
            return 0;
        }
        if (this._flags['i' + key] != null) {
            return this._flags['i' + key];
        }
        let flag: ABTestingFlag = app.App.installTime % 10 <= this._config[key] ? ABTestingFlag.Valid : ABTestingFlag.Invalid;
        this._flags['i' + key] = flag;
        app.publisher.analytics.setProperty('i' + key, flag);
        return flag;
    }

    /**
     * 获取临时ABTesting模块的Flag
     * @param key 模块名，第一次取后结果会被保存起来，之后取相同名称模块的Flag，返回第一次的FLag
     * @returns 
     */
    public getTempFlag(key: string): ABTestingFlag {
        if (!Object.prototype.hasOwnProperty.call(this._config, key)) {
            console.warn(`[ABTesting]未设置${key}的占比设置, 默认返回Invalid.`);
            return 0;
        }
        if (Object.prototype.hasOwnProperty.call(this._flags, key)) {
            return this._flags[key];
        }
        let flag: ABTestingFlag = Date.now() % 10 <= this._config[key] ? ABTestingFlag.Valid : ABTestingFlag.Invalid;
        this._flags[key] = flag;
        app.publisher.analytics.setProperty(key, flag);
        return flag;
    }

}

/**
 * AB测试
 */
export var ab: ABTesting = new ABTesting();
